using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Private_Asset_Folders : Deepcode.Flux.Core.UI.AdministrationModulePage
{
	#region Permission Code Override
	public override string RequiredPermissionCode { get { return "FluxAmAccess"; } }
	#endregion
	#region Rootpath
	/// <summary>
	/// Specify the root path to use
	/// </summary>
	protected string RootPath
	{
		get
		{
			object o = Session["AssetRootPath"];
			if( o == null ) return "~/assets";
			return (string) o;
		}
	}
	#endregion
	#region Page Load Event
	/// <summary>
	/// Page Load event
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!Page.IsPostBack)
		{
			// Populate the tree for on-demand loading
			CreateRootAndBind();
			SelectLastPath();
		}
	}
	#endregion
	#region Initialisation
	/// <summary>
	/// Page initialisation
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Init(object sender, EventArgs e)
	{
		_tree.TreeNodeExpanded += new TreeNodeEventHandler(_tree_TreeNodeExpanded);
		_tree.TreeNodeCollapsed += new TreeNodeEventHandler(_tree_TreeNodeCollapsed);
		_tree.TreeNodePopulate += new TreeNodeEventHandler(_tree_TreeNodePopulate);
		_tree.SelectedNodeChanged += new EventHandler(_tree_SelectedNodeChanged);
	}
	#endregion
	#region Tree Databinding
	/// <summary>
	/// Creates the root directory entry and binds it's data
	/// </summary>
	protected void CreateRootAndBind()
	{
		string UniqueValue = this.RootPath;
		string fullPath = Server.MapPath(UniqueValue);

		if( ! System.IO.Directory.Exists( fullPath )) return;
		
		TreeNode node = new TreeNode();
		node.Text = UniqueValue.Substring(1);
		node.Value = UniqueValue;
		node.ImageUrl = "~/admin/private/asset/img/folderopen.gif";
		node.PopulateOnDemand = false;
		node.Expanded = true;
		this._tree.Nodes.Add( node );
		BindTreeData( node.ChildNodes, UniqueValue );
	}
	/// <summary>
	/// Loads the data from the distro tree and devices into the tree
	/// </summary>
	protected void BindTreeData(TreeNodeCollection tnc, string ParentPath)
	{
		string fullPath = Server.MapPath( ParentPath );

		// Ensure the fullpath exists
		if(!System.IO.Directory.Exists( fullPath )) return;

		// Get a list of directories in the dir
		string [] subdirs = System.IO.Directory.GetDirectories( fullPath );
		
		// Add the tree nodes
		foreach (string sd in subdirs)
		{
			string subdir = System.IO.Path.GetFileName( sd );
			string UniqueValue = String.Format("{0}/{1}", ParentPath, subdir);

			TreeNode node = new TreeNode();
			node.Text = subdir;
			node.Value = UniqueValue;
			node.ImageUrl = "~/admin/private/asset/img/folderclosed.gif";
			// See if there are any sub directories
			if( ! HasContent( UniqueValue ) )
			{
				node.PopulateOnDemand = false;
				node.Expanded = false;
			}
			else
			{
				node.PopulateOnDemand = true;

				bool isExpand = IsExpanded(UniqueValue);
				node.Expanded = isExpand;
				if (isExpand)
					node.ImageUrl = "~/admin/private/asset/img/folderopen.gif";
			}

			tnc.Add( node );
		}
	}
	/// <summary>
	/// Determines if the virtual directory path has any files or folders
	/// </summary>
	/// <param name="vdir"></param>
	/// <returns></returns>
	private bool HasContent(string vdir)
	{
		string pdir = Server.MapPath( vdir );
		if( System.IO.Directory.GetDirectories( pdir ).Length > 0 ) return true;
		//if( System.IO.Directory.GetFiles( pdir ).Length > 0 ) return true;
		return false;
	}
	/// <summary>
	/// On demand population of data into a tree view node
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void _tree_TreeNodePopulate(object sender, TreeNodeEventArgs e)
	{
		// Get the unique value 
		string uniqueValue = e.Node.Value;
		BindTreeData(e.Node.ChildNodes, uniqueValue);
	}
	/// <summary>
	/// A node in the tree has been collapsed - track it and 
	/// change the image to show a closed node.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void _tree_TreeNodeCollapsed(object sender, TreeNodeEventArgs e)
	{
		e.Node.ImageUrl = "~/admin/private/asset/img/folderclosed.gif";
		RemoveExpand(e.Node.Value);
	}
	/// <summary>
	/// A node in the tree has been expanded - track it and
	/// change the image to show an open node.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void _tree_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
	{
		e.Node.ImageUrl = "~/admin/private/asset/img/folderopen.gif";
		AddExpand(e.Node.Value);
	}
	/// <summary>
	/// User has selected a different node - load the directory panel
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void _tree_SelectedNodeChanged(object sender, EventArgs e)
	{
		TreeNode n = _tree.SelectedNode;
		
		// Store last selected path
		SetUserSetting("ASSETMANAGERLASTPATH", n.Value);

		// open files panel for the selected folder
		ClientScript.RegisterStartupScript( typeof(Private_Asset_Folders),
			"loadFiles",
			"this.parent.loadfiles('" + n.Value + "');",
			true);
	}
	#endregion
	#region Expand / Collapse tracking
	/// <summary>
	/// Get the session containing the list of open node keys
	/// </summary>
	/// <returns></returns>
	private ArrayList GetSession()
	{
		ArrayList exList = (ArrayList)Session["asset_AssetTree"];

		if (exList == null )
		{
			exList = new ArrayList();
			Session["asset_AssetTree"] = exList;
		}
		return exList;
	}
	/// <summary>
	/// Adds the specified unique key value to the list of expanded keys
	/// </summary>
	/// <param name="uValue"></param>
	private void AddExpand(string uValue)
	{
		ArrayList l = GetSession();
		if (l.Contains(uValue)) return;
		l.Add(uValue);
	}
	/// <summary>
	/// Removes the specified unique key value from the list of expanded keys
	/// </summary>
	/// <param name="uValue"></param>
	private void RemoveExpand(string uValue)
	{
		ArrayList l = GetSession();
		l.Remove(uValue);
	}
	/// <summary>
	/// Determines if the specified unique key value is in the list of expanded keys
	/// </summary>
	/// <param name="uValue"></param>
	/// <returns></returns>
	private bool IsExpanded(string uValue)
	{
		ArrayList l = GetSession();
		if (l.Contains(uValue)) return true;
		return false;
	}
	#endregion
	#region Last path restoration
	/// <summary>
	/// Retrieves information about the last accessed path
	/// so that when re-binding data we can go to this location.
	/// </summary>
	protected string __LASTPATH = "";
	protected string LASTPATH
	{
		get
		{
			if (__LASTPATH != "") return __LASTPATH;
			__LASTPATH = this.UserSetting("ASSETMANAGERLASTPATH", this.RootPath);
			
			if( (!Page.IsPostBack) && (GetAttribute("SELPATH", "")!=""))
				return GetAttribute("SELPATH", "");

			return __LASTPATH;
		}
	}
	/// <summary>
	/// Selects the path that was last used
	/// </summary>
	protected void SelectLastPath()
	{
		// Get list of ordered keys and list of nodes at root
		string [] nodekeys = GetNodeKeys();
		TreeNodeCollection tnc = _tree.Nodes;
		
		// Go through each key finding at the current
		// level and cascading through child nodes until
		// all keys are found or we cannot continue
		foreach (string s in nodekeys)
		{
			bool bFound = false;
			foreach (TreeNode node in tnc)
			{
				if (node.Value == s)
				{
					node.Select();
					node.Expanded = true;
					tnc = node.ChildNodes;
					bFound = true;
					break;
				}
			}
			if( ! bFound ) return;
		}
	}
	/// <summary>
	/// Get array of unique values that should be selected
	/// in order to open the path to the final location
	/// </summary>
	/// <returns></returns>
	protected string[] GetNodeKeys()
	{
		ArrayList result = new ArrayList();
		
		// Split the path up
		result.Add(this.RootPath);
		string lpa = LASTPATH;
		if (lpa.StartsWith(this.RootPath))
		{
			string lp = lpa.Substring(this.RootPath.Length);
			string[] lps = lp.Split('/');
			string lastadded = this.RootPath;

			if( lps.Length > 0 )
			{
				for (int x = 0; x < lps.Length; x++)
				{
					if( lps[x] == "" ) continue;
					result.Add(String.Format("{0}/{1}", lastadded, lps[x]));
					lastadded += "/" + lps[x];
				}
			}
		}

		return result.ToArray(typeof(string)) as string [];
	}
	#endregion
}
